/*
 * Copyright 2015 Alan.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package me.alanz.screencapture.view;

import com.melloware.jintellitype.JIntellitype;
import me.alanz.screencapture.FXMain;
import me.alanz.screencapture.tool.DateTool;
import me.alanz.screencapture.tool.ImageTool;
import me.alanz.screencapture.model.ScreenCapture;
import me.alanz.screencapture.tool.AlertTool;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.Tooltip;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

/**
 * FXML Controller class
 *
 * @author Alan
 */
public class MainFXMLController implements Initializable {

    private static final Logger logger = Logger.getLogger(MainFXMLController.class.getName());
    @FXML
    private RadioButton cbFull;
    @FXML
    private RadioButton cbFix;
    @FXML
    private RadioButton cbManual;
    @FXML
    private Label lblFix;
    @FXML
    private ToggleGroup captureType;
    @FXML
    private Label lblMessage;
    @FXML
    private Button btnFix;
    @FXML
    private TextField txtFile;
    @FXML
    private Button btnCapture;

    /**
     * Initializes the controller class.
     *
     * @param url
     * @param rb
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        lblMessage.setManaged(false);

        ObservableList<Toggle> toggles = captureType.getToggles();
        for (Toggle toggle : toggles) {
            if (toggle instanceof RadioButton) {
                RadioButton rbtn = (RadioButton) toggle;
                if (rbtn.getText().equals(FXMain.getSetting().getDefaultCaptureType())) {
                    rbtn.setSelected(true);
                }
            }
        }
        txtFile.setText(FXMain.getSetting().getDirectory());
        showFixRectangle(FXMain.getSetting().getFixedRectangle());

        captureType.selectedToggleProperty().addListener((ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) -> {
            if (newValue instanceof RadioButton) {
                RadioButton rbtn = (RadioButton) newValue;
                FXMain.getSetting().setDefaultCaptureType(rbtn.getText());
            }
        });

        //第一步：注册热键，第一个参数表示该热键的标识，第二个参数表示组合键，如果没有则为0，第三个参数为定义的主要热键
        //44是Print Screen
        //JIntellitype.getInstance().registerHotKey(0, JIntellitype.MOD_ALT, 44);
        //第2个参数0表示没有
        JIntellitype.getInstance().registerHotKey(0, 0, 44);

        //第二步：添加热键监听器
        JIntellitype.getInstance().addHotKeyListener((int markCode) -> {
            switch (markCode) {
                case 0:
                    Platform.runLater(btnCapture::fire);
                    break;
            }
        });

        btnCapture.setTooltip(new Tooltip("快捷键: PrintScreen"));
    }

    @FXML
    private void doCapture(ActionEvent event) {
        logger.log(Level.INFO, "截图");
        Toggle selectedToggle = captureType.getSelectedToggle();
        if (selectedToggle == null) {
            lblMessage.setText("请先选择一个截图类型!");
            lblMessage.setManaged(true);
            lblMessage.setVisible(true);
        } else {
            final File dir = new File(FXMain.getSetting().getDirectory() + File.separator);
            if (!dir.exists()) {
                lblMessage.setText("截图保存路径错误或不存在! 请重新选择路径!");
                lblMessage.setManaged(true);
                lblMessage.setVisible(true);
                return;
            }

            final File file = new File(FXMain.getSetting().getDirectory() + File.separator
                    + DateTool.getCurrentTime().replaceAll("[:\\s]", "-") + ".png");

            ScreenCapture capture = new ScreenCapture();
            if (selectedToggle == cbFull) {
                capture.captureFullScreen();
            } else if (selectedToggle == cbFix) {
                Rectangle fixedArea = getFixedArea();
                if (fixedArea == null) {
                    lblMessage.setText("请先选择固定的截图区域!");
                    lblMessage.setManaged(true);
                    lblMessage.setVisible(true);
                    return;
                }

                capture.captureRectangle(fixedArea);
            } else if (selectedToggle == cbManual) {
                capture.captureRectangle();
            }

            if (capture.getPickedImage() != null) {
                try {
                    ImageTool.saveAsPNG(capture.getPickedImage(), file);
                } catch (IOException ex) {
                    logger.log(Level.SEVERE, null, ex);
                    AlertTool.Alert(ex.getMessage());
                }
                show(capture.getPickedImage());
            }

            lblMessage.setManaged(false);
            lblMessage.setVisible(false);
        }
    }

    @FXML
    private void doSelectFixArea(ActionEvent event) {
        ScreenCapture capture = new ScreenCapture();
        capture.setOldRectangle(getFixedArea());
        capture.captureRectangle();
        if (capture.getPickedImage() != null) {
            Rectangle r = capture.getRectangle();

            FXMain.getSetting().setFixedRectangle(r);
            showFixRectangle(r);
        }
    }

    private Rectangle getFixedArea() {
        String text = lblFix.getText();
        text = text.replaceAll("[(,)]", " ");
        text = text.replaceAll("\\s+", " ");
        text = text.trim();
        String[] split = text.split(" ");

        if (split.length != 4) {
            return null;
        }

        final Rectangle rectangle = new Rectangle(
                Integer.parseInt(split[0]),
                Integer.parseInt(split[1]),
                Integer.parseInt(split[2]),
                Integer.parseInt(split[3]));
        return rectangle;
    }

    private void showFixRectangle(Rectangle r) {
        lblFix.setText("(" + (int) r.getX() + ", " + (int) r.getY()
                + ", " + (int) r.getWidth() + ", " + (int) r.getHeight() + ")");
    }

    private void show(BufferedImage image) {
        Dimension size = Toolkit.getDefaultToolkit().getScreenSize();

        final Stage stage = new Stage(StageStyle.UNDECORATED);
        BorderPane bp = new BorderPane();
        final ImageView imageView = new ImageView(ImageTool.convert(image));
        bp.setCenter(imageView);
        stage.setScene(new Scene(bp, size.getWidth(), size.getHeight()));
        stage.setFullScreen(true);
        stage.setFullScreenExitHint("");
        stage.setAlwaysOnTop(true);
        stage.show();

        final Timer timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                Platform.runLater(() -> {
                    stage.close();
                });

                timer.purge();
                timer.cancel();
            }
        }, 800);
    }

    @FXML
    private void doSelectPath(ActionEvent event) {
        DirectoryChooser chooser = new DirectoryChooser();
        File oldDir = new File(FXMain.getSetting().getDirectory() + File.separator);
        if (oldDir.exists()) {
            chooser.setInitialDirectory(oldDir);
        }
        File dir = chooser.showDialog(txtFile.getScene().getWindow());
        if (dir != null) {
            txtFile.setText(dir.getAbsolutePath());
            FXMain.getSetting().setDirectory(dir.getAbsolutePath());
        }
    }
}
